<?php
namespace app\index\controller;

use app\common\controller\Base;
use app\common\controller\IndexBase;
use think\Config;
use think\Db;


class Wxpay extends  IndexBase
{
//    private $company;

    //初始化
    public function _initialize()
    {
        //引入WxPayPubHelper
        vendor('WxPayPubHelper.WxPayPubHelper');
//        $this->company = Db::name("Config")->where(array("name"=>"company","extend_value"=>"weixin"))->value("value");
    }

//    public function index(){
//        echo $this->company;
//        exit();
//        //使用jsapi接口
//        $jsApi = new \JsApi_pub();
//        exit();

//    }

    /**
     * 购物商城订单支付
     * @return [type] [description]
     */
    public function pay()
    {


        $map = input('param.');

        if(isset($map["id"]) && empty($map["id"])){
            $this->error('缺少参数ID');
        }
		$data = explode("_",$map["id"]);

        if( $data[0] == "gw" ){

            $M = Db::name("Order");
            $filed = "name,price,order_sn";
        }else{

            $M = Db::name("ActivationOrders");
            $filed = "name,price,order_code,use_cash";
        }
        $order = $M->field( $filed)->where("id",$data[1])->find();
        if( isset($order["use_cash"]) ){
            $order["price"] = $order["price"]-$order["use_cash"];
        }
		
        //使用jsapi接口
        $jsApi = new \JsApi_pub();

        //=========步骤1：网页授权获取用户openid============
        //通过code获得openid
        if (!isset($_GET['code'])){

            //触发微信返回code码
            $url = $jsApi->createOauthUrlForCode(request()->domain()."/index/Wxpay/pay?id=".$map["id"]);

            Header("Location: $url");
            exit();
        }else{

            //获取code码，以获取openid
            $code = $_GET['code'];
            $jsApi->setCode($code);
            $openid = $jsApi->getOpenId();
        }

        //=========步骤2：使用统一支付接口，获取prepay_id============
        //使用统一支付接口
        $unifiedOrder = new \UnifiedOrder_pub();

        //设置统一支付接口参数
        //设置必填参数
        //appid已填,商户无需重复填写
        //mch_id已填,商户无需重复填写
        //noncestr已填,商户无需重复填写
        //spbill_create_ip已填,商户无需重复填写
        //sign已填,商户无需重复填写
        $unifiedOrder->setParameter("openid",$openid);//商品描述
        $unifiedOrder->setParameter("body",$this->configArr["company"].$order['name']);//商品描述
        //自定义订单号，此处仅作举例

        //$price = $order['price']*100;
        $price = 1;
        $unifiedOrder->setParameter("out_trade_no",$order['order_code']);//商户订单号
        $unifiedOrder->setParameter("total_fee",$price);//总金额
        $unifiedOrder->setParameter("notify_url",'http://'.$_SERVER['HTTP_HOST'].'/index/Wxpay/notify');//通知地址
        $unifiedOrder->setParameter("trade_type","JSAPI");//交易类型
        //非必填参数，商户可根据实际情况选填
        //$unifiedOrder->setParameter("sub_mch_id","XXXX");//子商户号
        //$unifiedOrder->setParameter("device_info","XXXX");//设备号
        //$unifiedOrder->setParameter("attach","XXXX");//附加数据
        //$unifiedOrder->setParameter("time_start","XXXX");//交易起始时间
        //$unifiedOrder->setParameter("time_expire","XXXX");//交易结束时间
        //$unifiedOrder->setParameter("goods_tag","XXXX");//商品标记
        //$unifiedOrder->setParameter("openid","XXXX");//用户标识
        //$unifiedOrder->setParameter("product_id","XXXX");//商品ID

        $prepay_id = $unifiedOrder->getPrepayId();
        //=========步骤3：使用jsapi调起支付============
        $jsApi->setPrepayId($prepay_id);

        $jsApiParameters = $jsApi->getParameters();
        $this->assign('data',$order);
        $this->assign('jsApiParameters',$jsApiParameters);
        return $this->fetch();
    }

    /**
     * 购物商城订单回调
     * @return [type] [description]
     */
    public function notify()
    {

        //使用通用通知接口
        $notify = new \Notify_pub();
		
        //存储微信的回调
        $xml = file_get_contents("php://input");

        $notify->saveData($xml);

        //验证签名，并回应微信。
        //对后台通知交互时，如果微信收到商户的应答不是成功或超时，微信认为通知失败，
        //微信会通过一定的策略（如30分钟共8次）定期重新发起通知，
        //尽可能提高通知的成功率，但微信不保证通知最终能成功。

        if($notify->checkSign() == FALSE){
            $notify->setReturnParameter("return_code","FAIL");//返回状态码
            $notify->setReturnParameter("return_msg","签名失败");//返回信息
        }else{
            $notify->setReturnParameter("return_code","SUCCESS");//设置返回码
        }
        $returnXml = $notify->returnXml();
        echo $returnXml;

        //==商户根据实际情况设置相应的处理流程，此处仅作举例=======

        //以log文件形式记录回调信息


		create_api_log("【接收到的notify通知】:\n".$xml."\n","weixin");
        //log_result($log_name,"【接收到的notify通知】:\n".$xml."\n");

        if($notify->checkSign() == TRUE)
        {
			Db::name("Test")->insert(array("msg"=>"order_code3="));
            if ($notify->data["return_code"] == "FAIL") {
                //此处应该更新一下订单状态，商户自行增删操作
				create_api_log("【通信出错】:\n".$xml."\n","weixin");
                //log_result($log_name,"【通信出错】:\n".$xml."\n");
            }
            elseif($notify->data["result_code"] == "FAIL"){
                //此处应该更新一下订单状态，商户自行增删操作
				create_api_log("【业务出错】:\n".$xml."\n","weixin");

            }
            else{
                //此处应该更新一下订单状态，商户自行增删操作
                $orderno = $notify->data['out_trade_no'];
                $orderpayno = $notify->data['transaction_id'];
                $order_tatal = $notify->data['total_fee'] / 100;
                $where['order_code'] = $orderno;
				
                if(strpos($orderno,'gw') !== false){

                    $M_Order = Db::name("PackageOrder");
                    $type = "gw";
                    $filed = "id,package_id,price,status";
                }else{

                    $M_Order = Db::name("ActivationOrders");
                    $type = "js";
                    $filed = "id,package_id,price,use_cash,status";
                }


                $order = $M_Order->field($filed)->where($where)->find();
                if( isset($order["use_cash"]) ){
                    $order["price"] = $order["price"] - $order["use_cash"];
                }
                //if($order_tatal == $order['price'] && $order['status'] != 15  ){
               if( $order['status'] != 15 ){

                    //更新订单状态
                    $Oczdata = array();
                    $Oczdata['status'] = 15;
                    $Oczdata['pay_type'] = 2;
                    $Oczdata['pay_code'] = $orderpayno;
                    $Oczdata['pay_time'] = time();

                    $M_Order->where($where)->update($Oczdata);

                    $proceeds = app_service("common","Proceeds");
                    $proceeds->buy_proceeds($order['id'],$type);

                    Db::name("Package")->where(array('id'=>$order['package_id']))->setInc('buy_sum');

                    // 通知管理者有用户购买了商品
//                    $info = '用户:'.$user['nickname'].';付款:'.$order_tatal.';购买了:'.$order['name'].';订单号：'.$orderno.'。请及时处理';
//                    send_message(C('admin_openid'), $info);
                }

				create_api_log("【支付成功】:\n".$xml."\n","weixin");
                //log_result($log_name,"【支付成功】:\n".$xml."\n");
            }

            //商户自行增加处理流程,
            //例如：更新订单状态
            //例如：数据库操作
            //例如：推送支付完成信息
        }
    }




    /**
     * 微信扫码支付模式二
     * @return [type] [description]
     */
    public function qrcode2(){

        //订单号  可以自定义
        $curTime = explode (" ", microtime());
        $curMicroTime = $curTime[1]."".round(($curTime[0]*1000));
        $out_trade_no = strval($curMicroTime);
        $order['order_no'] = $out_trade_no;

        $total_fee =1;//价钱 记得要*100
        $body = "微信支付";//描述

        //使用统一支付接口
        $unifiedOrder = new \UnifiedOrder_pub();
        // $unifiedOrder->APPID = "";//微信公众号身份的唯一标识。审核通过后，在微信发送的邮件中查看
        // $unifiedOrder->MCHID = "";//微信商户号
        // $unifiedOrder->KEY   = "";//商户支付密钥Key。

        //设置统一支付接口参数
        //设置必填参数
        $unifiedOrder->setParameter("body",$body);//商品描述
        //自定义订单号，此处仅作举例
        $timeStamp = time();
        $unifiedOrder->setParameter("out_trade_no",$order['order_no']);//商户订单号
        $unifiedOrder->setParameter("total_fee",$total_fee);//总金额
        $unifiedOrder->setParameter("notify_url", 'http://'.$_SERVER['HTTP_HOST'].'/index/Wxpay/qrcode2_notify');//通知回调地址
        $unifiedOrder->setParameter("trade_type","NATIVE");//交易类型
        //非必填参数，商户可根据实际情况选填
        //$unifiedOrder->setParameter("sub_mch_id","XXXX");//子商户号
        //$unifiedOrder->setParameter("device_info","XXXX");//设备号
        //$unifiedOrder->setParameter("attach","XXXX");//附加数据
        //$unifiedOrder->setParameter("time_start","XXXX");//交易起始时间
        //$unifiedOrder->setParameter("time_expire","XXXX");//交易结束时间
//         $unifiedOrder->setParameter("goods_tag","");//商品标记
//         $unifiedOrder->setParameter("openid","19405");//用户标识
        //$unifiedOrder->setParameter("product_id","XXXX");//商品ID
        //获取统一支付接口结果
        $unifiedOrderResult = $unifiedOrder->getResult();
//         var_dump($unifiedOrder);
        //商户根据实际情况设置相应的处理流程
        if ($unifiedOrderResult["return_code"] == "FAIL")
        {
            //商户自行增加处理流程
            echo "通信出错：".$unifiedOrderResult['return_msg']."<br>";
        }
        elseif($unifiedOrderResult["result_code"] == "FAIL")
        {
            //商户自行增加处理流程
            echo "错误代码：".$unifiedOrderResult['err_code']."<br>";
            echo "错误代码描述：".$unifiedOrderResult['err_code_des']."<br>";
        }
        elseif($unifiedOrderResult["code_url"] != NULL)
        {
            //从统一支付接口获取到code_url
            $code_url = $unifiedOrderResult["code_url"];
            //商户自行增加处理流程
            //......
        }
        $this->assign('out_trade_no',$order['order_no']);
        $this->assign('code_url',$code_url);
        $this->assign('unifiedOrderResult',$unifiedOrderResult);
        $this->title ="微信支付";
        $this->display();
    }


    public function qrcode2_notify()
    {

        //使用通用通知接口
        $notify = new \Notify_pub();

        //存储微信的回调
        $xml = $GLOBALS['HTTP_RAW_POST_DATA'];
        $notify->saveData($xml);

        //验证签名，并回应微信。
        //对后台通知交互时，如果微信收到商户的应答不是成功或超时，微信认为通知失败，
        //微信会通过一定的策略（如30分钟共8次）定期重新发起通知，
        //尽可能提高通知的成功率，但微信不保证通知最终能成功。
        if($notify->checkSign() == FALSE){
            $notify->setReturnParameter("return_code","FAIL");//返回状态码
            $notify->setReturnParameter("return_msg","签名失败");//返回信息
        }else{
            $notify->setReturnParameter("return_code","SUCCESS");//设置返回码
        }
        $returnXml = $notify->returnXml();
        echo $returnXml;

        //==商户根据实际情况设置相应的处理流程，此处仅作举例=======

        //以log文件形式记录回调信息
        //         $log_ = new Log_();
        $log_name= __ROOT__."/Public/notify_url.log";//log文件路径

        $this->log_result($log_name,"【接收到的notify通知】:\n".$xml."\n");

        if($notify->checkSign() == TRUE)
        {
            if ($notify->data["return_code"] == "FAIL") {
                //此处应该更新一下订单状态，商户自行增删操作
                log_result($log_name,"【通信出错】:\n".$xml."\n");
            }
            elseif($notify->data["result_code"] == "FAIL"){
                //此处应该更新一下订单状态，商户自行增删操作
                log_result($log_name,"【业务出错】:\n".$xml."\n");
            }
            else{
                //此处应该更新一下订单状态，商户自行增删操作

                log_result($log_name,"【支付成功】:\n".$xml."\n");
            }

            //商户自行增加处理流程,
            //例如：更新订单状态
            //例如：数据库操作
            //例如：推送支付完成信息
        }
    }

    //查询订单
    public function orderQuery()
    {
        // out_trade_no='+$('out_trade_no').value,
        //退款的订单号
        if (!isset($_POST["out_trade_no"]))
        {
            $out_trade_no = " ";
        }else{
            $out_trade_no = $_POST["out_trade_no"];
            //使用订单查询接口
            $orderQuery = new \OrderQuery_pub();
            //设置必填参数
            //appid已填,商户无需重复填写
            //mch_id已填,商户无需重复填写
            //noncestr已填,商户无需重复填写
            //sign已填,商户无需重复填写
            $orderQuery->setParameter("out_trade_no","$out_trade_no");//商户订单号
            //非必填参数，商户可根据实际情况选填
            //$orderQuery->setParameter("sub_mch_id","XXXX");//子商户号
            //$orderQuery->setParameter("transaction_id","XXXX");//微信订单号

            //获取订单查询结果
            $orderQueryResult = $orderQuery->getResult();

            //商户根据实际情况设置相应的处理流程,此处仅作举例
            if ($orderQueryResult["return_code"] == "FAIL") {
                $this->error($out_trade_no);
            }
            elseif($orderQueryResult["result_code"] == "FAIL"){
                // $this->ajaxReturn('','支付失败！',0);
                $this->error($out_trade_no);
            }
            else{
                $i=$_SESSION['i'];
                $i--;
                $_SESSION['i'] = $i;
                //判断交易状态
                switch ($orderQueryResult["trade_state"])
                {
                    case SUCCESS:
                        $this->success("支付成功！");
                        break;
                    case REFUND:
                        $this->error("转入退款".$i);
                        break;
                    case NOTPAY:
                        $this->error("未支付订单".$i);
                        //  $this->ajaxReturn($orderQueryResult["trade_state"], "支付成功", 1);
                        break;
                    case CLOSED:
                        $this->error("关闭订单".$i);
                        break;
                    case PAYERROR:
                        $this->error("支付失败".$orderQueryResult["trade_state"]);
                        break;
                    default:
                        $this->error("未知失败".$orderQueryResult["trade_state"]);
                        break;
                }
            }
        }
    }

    /**
     * 微信扫码支付模式一
     * @return [type] [description]
     */
    public function native_pay()
    {
        //设置静态链接
        $nativeLink = new \NativeLink_pub();

        //设置静态链接参数
        //设置必填参数
        //appid已填,商户无需重复填写
        //mch_id已填,商户无需重复填写
        //noncestr已填,商户无需重复填写
        //time_stamp已填,商户无需重复填写
        //sign已填,商户无需重复填写
        $product_id = C('appid')."static";//自定义商品id
        $nativeLink->setParameter("product_id",$product_id);//商品id
        //获取链接
        $product_url = $nativeLink->getUrl();
        //使用短链接转换接口
        $shortUrl = new \ShortUrl_pub();
        //设置必填参数
        //appid已填,商户无需重复填写
        //mch_id已填,商户无需重复填写
        //noncestr已填,商户无需重复填写
        //sign已填,商户无需重复填写
        $shortUrl->setParameter("long_url",$product_url);//URL链接
        //获取短链接
        $codeUrl = $shortUrl->getShortUrl();

        $this->assign('product_url',$product_url);
        $this->assign('codeUrl',$codeUrl);
        $this->display();

    }

    /**
     * 扫码支付(模式一)成功回调
     */
    public function qrcode_notify(){
        //以log文件形式记录回调信息，用于调试
        $log_name = __ROOT__."/Public/native_call.log";
        //使用native通知接口
        $nativeCall = new \NativeCall_pub();

        //接收微信请求
        $xml = $GLOBALS['HTTP_RAW_POST_DATA'];
        log_result($log_name,"【接收到的native通知】:\n".$xml."\n");
        $nativeCall->saveData($xml);

        if($nativeCall->checkSign() == FALSE){
            $nativeCall->setReturnParameter("return_code","FAIL");//返回状态码
            $nativeCall->setReturnParameter("return_msg","签名失败");//返回信息
        }
        else
        {
            //提取product_id
            $product_id = $nativeCall->getProductId();

            //使用统一支付接口
            $unifiedOrder = new \UnifiedOrder_pub();

            //根据不同的$product_id设定对应的下单参数，此处只举例一种
            switch ($product_id)
            {

                case C('appid')."static"://与native_call_qrcode.php中的静态链接二维码对应
                    //设置统一支付接口参数
                    //设置必填参数
                    //appid已填,商户无需重复填写
                    //mch_id已填,商户无需重复填写
                    //noncestr已填,商户无需重复填写
                    //spbill_create_ip已填,商户无需重复填写
                    //sign已填,商户无需重复填写
                    $unifiedOrder->setParameter("body","贡献一分钱");//商品描述
                    //自定义订单号，此处仅作举例
                    $timeStamp = time();
                    $out_trade_no = C('WxPayConf_pub.APPID').$timeStamp;
                    $unifiedOrder->setParameter("out_trade_no",$out_trade_no);//商户订单号             $unifiedOrder->setParameter("product_id","$product_id");//商品ID
                    $unifiedOrder->setParameter("total_fee","1");//总金额
                    $unifiedOrder->setParameter("notify_url",C('WxPayConf_pub.NOTIFY_URL'));//通知地址
                    $unifiedOrder->setParameter("trade_type","NATIVE");//交易类型
                    $unifiedOrder->setParameter("product_id",$product_id);//用户标识
                    //非必填参数，商户可根据实际情况选填
                    //$unifiedOrder->setParameter("sub_mch_id","XXXX");//子商户号
                    //$unifiedOrder->setParameter("device_info","XXXX");//设备号
                    //$unifiedOrder->setParameter("attach","XXXX");//附加数据
                    //$unifiedOrder->setParameter("time_start","XXXX");//交易起始时间
                    //$unifiedOrder->setParameter("time_expire","XXXX");//交易结束时间
                    //$unifiedOrder->setParameter("goods_tag","XXXX");//商品标记
                    //$unifiedOrder->setParameter("openid","XXXX");//用户标识

                    //获取prepay_id
                    $prepay_id = $unifiedOrder->getPrepayId();
                    //设置返回码
                    //设置必填参数
                    //appid已填,商户无需重复填写
                    //mch_id已填,商户无需重复填写
                    //noncestr已填,商户无需重复填写
                    //sign已填,商户无需重复填写
                    $nativeCall->setReturnParameter("return_code","SUCCESS");//返回状态码
                    $nativeCall->setReturnParameter("result_code","SUCCESS");//业务结果
                    $nativeCall->setReturnParameter("prepay_id",$prepay_id);//预支付ID

                    break;
                default:
                    //设置返回码
                    //设置必填参数
                    //appid已填,商户无需重复填写
                    //mch_id已填,商户无需重复填写
                    //noncestr已填,商户无需重复填写
                    //sign已填,商户无需重复填写
                    $nativeCall->setReturnParameter("return_code","SUCCESS");//返回状态码
                    $nativeCall->setReturnParameter("result_code","FAIL");//业务结果
                    $nativeCall->setReturnParameter("err_code_des","此商品无效");//业务结果
                    break;
            }

        }

        //将结果返回微信
        $returnXml = $nativeCall->returnXml();
        log_result($log_name,"【返回微信的native响应】:\n".$returnXml."\n");
        echo $returnXml;

    }

}
